﻿
var people = [];
var conversations = [];
var selectedUserName = -1;
var selectedConver = -1;
var dtTimer = -1;
var dtTimerInt = 10000;
var opacVal = 0.7;
var minimized = false;
var chat;
var windowTitle = document.title;
var _myLoginName = "";
var _typing = false;


function InitEasyChat() {
    $('body').append('<div id="easychat"></div>');
    $("#easychat").append('<div id="easychat-conver"></div>');
    $("#easychat").append('<div id="easychat-people"></div>');
    $("#easychat-people").append('<div id="people-header">');
    $("#people-header").append('<h3>Online User(s)</h3>');
    $("#people-header").append('<div id="people-slider"/>');
    $("#people-header").append('<div id="people-window"></div>');

    $("#easychat-people").append('<div id="people-list"></div>');
    $("#easychat-people").append('<div id="people-mystatus">My Status:</div>');
    $("#people-mystatus").append('<input id="people-setonline" type="button" class="online"></input>');
    $("#people-mystatus").append('<input id="people-setaway" type="button" class="away"></input>');
    $("#people-mystatus").append('<input id="people-setbusy" type="button" class="busy"></input>');

    $("#people-slider").slider({
        min: 40,
        max: 100,
        value: 70,
        slide: function (event, ui) {
            opacVal = ui.value / 100;
            var converColor = getConverBGColor();
            $("#easychat-people, .conver").css({ 'background': converColor });
        }
    });

    $("#people-window").click(function () {
        $("#easychat-people").toggleClass('mini');
        minimized = $("#easychat-people").hasClass("mini");
        $("#easychat-people .name").each(function (i, o) {
            var name = $(o).data('name');

            $(o).text(getPrettyName(name));
        });
    }).click();
    // Declare a proxy to reference the hub. 
    chat = $.connection.chatHub;

    chat.client.setOnlineUsers = function (json) {
        OnSetOnlineUsers(json);
    }

    chat.client.someoneOnline = function (json) {
        OnSomeoneOnline(json);
    };
    chat.client.someoneOffline = function (json) {
        OnSomeoneOffline(json);
    }

    chat.client.receivePM = function (json) {
        OnReceivePM(json);
    }

    chat.client.sentPM = function (json) {
        OnSentPM(json);
    }

    chat.client.createdConver = function (json) {
        OnCreatedConver(json);
    }

    chat.client.connected = function (json) {
        _myLoginName = json;
    }

    chat.client.receivedTyping = function (converId) {
        OnReceivedTyping(converId);
    }
    chat.client.cenceledTyping = function (converId) {
        OnCanceledTyping(converId);
    }

    chat.client.receivedLastSeen = function (pmesageId, converId) {
        OnReceivedLastSeen(pmesageId, converId);
    }
    $.connection.hub.start().done(function () {

        getOnlineUser();
        $('#people-setonline').click(function () {
            setStatus("Online", this);
        });
        $('#people-setaway').click(function () {
            setStatus("Away", this);
        });
        $('#people-setbusy').click(function () {
            setStatus("Busy", this);
        });

        $('#people-setonline').click();
    });

}


function OnSetOnlineUsers(json) {
    $(json).each(function (i, o) {
        DisplayNewUser(o);
    });
}

function OnSomeoneOnline(presence) {
    var targetUser = presence.UserName;
    var filter = $(people).filter(function (i, o) {
        var id = o["UserName"];
        return id == targetUser;
    });
    if (filter.length > 0) {
        var personObj = filter[0];
        personObj["Status"] = presence.Status;
        personObj["LastUpdate"] = presence.LastUpdate;
        personObj["DisplayName"] = presence.DisplayName;
        var presenceHtml = getPresenceHtml(presence);
        $("#people-list div[data-id='" + escape(presence.UserName) + "']").html(presenceHtml);
        var statusClass = 'status ' + presence.Status.toLowerCase();
        $("#easychat-conver [data-user='" + escape(presence.UserName) + "'] .status").attr('class', statusClass);
    }
    else {
        DisplayNewUser(presence);
    }
}

function OnReceivePM(pmessage) {
    var from = pmessage.From;
    var msg = pmessage.Message;
    var when = pmessage.When;
    var to = pmessage.To;

    var conver = _getConverByID(pmessage.ConverID);

    if (conver) {
        pmessage.Read = false;
        appendMsg(conver, pmessage);
    }
    else {

        createConver(from);
        highlightConver(from);
    }

    SendAckPM(pmessage);
    //Calculate unread msg
    refreshUnreadPMCount();


}



function OnSentPM(pmessage) {
    var conver = _getConverByID(pmessage.ConverID);
    if (conver) {
        pmessage.Read = true;
        appendMsg(conver, pmessage);
    }
}

function OnCreatedConver(json) {

    conversations.push(json);
    var filter = $(people).filter(function (i, o) {
        return o.UserName == json.UserName || o.UserName == json.Creator;
    });
    var peopleObj = filter[0];
    //create base on user's status and name as conver title
    InitConver(json, peopleObj);
}

function SendAckPM(msg) {
    chat.server.sendAckPM(msg.ID);
}

function encodeHtml(html) {
    if (html.match(/\<img([\w\W]+?)\/>$/)) {
        return html;
    }
    if (html.match(/\<a([\w\W]+?)\>\Link<\/a>$/)) {
        return html
    }
    return html.replace(/&/g, '&amp;')
           .replace(/</g, '&lt;')
           .replace(/>/g, '&gt;')
           .replace(/"/g, '&quot;')
           .replace(/'/g, '&apos;');
}


function setStatus(status, dom) {
    chat.server.setStatus(status);
    $("#people-mystatus input").removeClass('highlight');
    $(dom).addClass('highlight');
}
function getOnlineUser() {
    chat.server.getOnlineUsers();
}

function sendPM(msg, converId) {
    chat.server.sendPM(converId, msg);
}

function sendLastSeen(converId) {
    chat.server.sendLastSeen(converId);
}
function OnCanceledTyping(converId) {
    var converDom = $("#easychat-conver .conver[data-id='" + converId + "']");
    if (converDom.length > 0) {
        $(converDom).find(".typing").remove();
        var bodyDom = $(converDom).find(".body");
        scrollToBottom(bodyDom[0])
    }
}
function OnReceivedTyping(converId) {
    var typingDom = "<div class='typing'>...</div>";
    var converDom = $("#easychat-conver .conver[data-id='" + converId + "']");
    if (converDom.length > 0) {
        var bodyDom = $(converDom).find(".body");
        $(bodyDom).append(typingDom);
        scrollToBottom(bodyDom[0])
    }
}

function OnReceivedLastSeen(msgId, converId) {
    var lastSeenDom = "<div class='seen'>Seen<div>";
    var converDom = $("#easychat-conver .conver[data-id='" + converId + "']");
    if (converDom.length > 0) {
        $(converDom).find(".seen").remove();
        $(converDom).find(".pm[id='pm-" + msgId + "']").after(lastSeenDom);

        var bodyDom = $(converDom).find(".body");
        scrollToBottom(bodyDom[0]);
    }
}

function DisplayNewUser(presence) {
    people.push(presence);
    var presenceHtml = getPresenceHtml(presence);
    var newDom = '<div class="people" data-id="' + escape(presence.UserName) + '">' + presenceHtml + '</div>';
    $('#people-list').append(newDom);
    $("#people-list .people[data-id='" + escape(presence.UserName) + "']").click(function () {
        createConver(presence);
    });
}

function getPresenceHtml(presence) {
    var name = getPrettyName(presence.DisplayName);
    return "<span class='status {0}'></span><span class='name' title='{1}' data-name='{2}'>{3}</span>"
    .replace("{0}", presence.Status.toLowerCase())
    .replace("{1}", presence.LastUpdate)
    .replace("{2}", presence.DisplayName)
    .replace("{3}", name);
}


function getPMHtml(pmObj) {
    var timeStamp = "";
    if (pmObj.When) {
        var d = new Date(pmObj.When);
        timeStamp = "data-d='" + pmObj.When + "' title='" + moment(d).fromNow() + "' ";
    }

    var text = "<span class='msg' " + timeStamp + ">" + encodeHtml(pmObj.Message) + "</span>";
    var cssClass = "pm you";

    if (pmObj.From.UserName == _myLoginName) {
        cssClass = "pm me";
    }
    return "<div class='{css}' id='pm-{id}'>{text}</div>"
	.replace("{css}", cssClass)
	.replace("{id}", pmObj.ID)
	.replace("{text}", text);
}

function createConver(presence) {
    var filter = $(conversations).filter(function (i, o) {
        return o.UserName == presence.UserName || o.Creator == presence.UserName;
    });

    if (filter.length == 0) {
        chat.server.createConver(presence.UserName);
    }
    else {
        var conver = filter[0];
        InitConver(conver, presence)
    }
}

function InitConver(conver, presence) {
    if (!conver.Init) {
        var msgHtml = "";

        $(conver.PM).each(function (i, o) {
            msgHtml += getPMHtml(o);
        });
        var status = typeof (presence) != "undefined" ? presence.Status : "Online";
        var title = typeof (presence) != "undefined" ? presence.DisplayName : "New Chat Room";

        var html = getNewConverHtml(conver.ID, status, title, msgHtml);
        $("#easychat-conver").prepend(html);

        if (typeof (presence) != "undefined") {
            $('#easychat-conver .conver[data-id="' + conver.ID + '"]').attr('data-user', escape(presence.UserName));
        }

        $('#easychat-conver .conver[data-id="' + conver.ID + '"] a.close')
        .click(function (e) {
            closeConver(conver.ID);
        });
        $('#easychat-conver .conver[data-id="' + conver.ID + '"] input[type="text"]')
        .bind('keydown', function (e) {
            if (e.keyCode == 13) {
                var msg = $(this).val();
                if (msg != "") {
                    _typing = false;
                    chat.server.cancelTyping(conver.ID);
                    sendPM(msg, conver.ID);
                    $(this).val("");
                }
            }
        })
		.bind('keyup', function (e) {
		    var msg = $(this).val();
		    if (!_typing && msg.length > 0) {
		        _typing = true;
		        chat.server.sendTyping(conver.ID);
		    }
		    if (_typing && msg.length == 0) {
		        chat.server.cancelTyping(conver.ID);
		        _typing = false;
		    }

		})
        .bind('focus', function (e) {
            highlightConver(conver.ID);
            var thisCount = getUnreadPMCount(conver.ID);
            if (thisCount > 0) {
                clearUnreadPMCount(conver.ID);
                sendLastSeen(conver.ID);
                refreshUnreadPMCount();
            }
        });

        var nestedCount = 0;
        $('#easychat-conver .conver[data-id="' + conver.ID + '"] .body')
		.bind('dragstart', function (e) { if (e.stopPropagation) { e.stopPropagation(); } return false; })
		.bind('dragenter', function (e) {
		    e.preventDefault();
		    nestedCount++;
		    if (nestedCount === 1 && !$(this).hasClass('dragin')) {
		        $(this).addClass('dragin');
		        $(this).append('<div id="drag-n-drop"></div>');
		    }

		})
		.bind('dragover', function (e) {
		    if (e.preventDefault) {
		        e.preventDefault();
		    }
		    e.originalEvent.dataTransfer.dropEffect = "link";
		    return false;
		})
		.bind('dragleave', function (e) {
		    e.preventDefault();
		    if (nestedCount === 1 && $(this).hasClass('dragin')) {

		        $(this).removeClass('dragin');
		        $(this).find("#drag-n-drop").remove();

		        console.log('leave');
		    }
		    nestedCount--;
		})
		.bind('drop', function (e) {

		    e.preventDefault();
		    e.stopPropagation();
		    if (e.originalEvent.dataTransfer && e.originalEvent.dataTransfer.files.length) {

		        console.log(e.originalEvent.dataTransfer.files);
		    }

		    nestedCount = 0;
		    if ($(this).hasClass('dragin')) {
		        $(this).removeClass('dragin');
		        $(this).find("#drag-n-drop").remove();
		    }

		    //process
		    processDragItem(e, conver.ID);
		    return false;
		})
		.bind('dragend', function (e) {
		    if (e.stopPropagation) {
		        e.stopPropagation();
		    }
		    return false;
		});


        scrollToBottom($("#easychat-conver").find(".body")[0]);
        conver.Init = true;
        if (dtTimer == -1) {
            dtTimer = setInterval(refreshDate, dtTimerInt);
        }
    }

    highlightConver(conver.ID);
}
function highlightConver(converId) {
    //Update current ConnID
    // var userName = presence.UserName;
    // selectedUserName = userName;
    selectedConver = converId;
    $(".conver").removeClass('highlight');
    $(".conver[data-id='" + converId + "']").addClass('highlight');

    //$('#people-list .people').removeClass('bold');
    //$("#people-list .people[data-id='" + escape(userName) + "']").addClass('bold');
}

function closeConver(converId) {
    if (selectedConver == converId) {
        selectedConver = -1;
    }
    $(".conver[data-id='" + converId + "']").remove();
    var conver = _getConverByID(converId);
    conver.Init = false;

    //Send Server to tell user closes conver
}

function getNewConverHtml(id, status, title, msgHtml) {
    var heading = '<div class="header"><span class="status {0}"></span>{1}<a class="close"></a></div>'
			.replace('{0}', status.toLowerCase())
			.replace('{1}', title);

    var body = '<div class="body">' + msgHtml + '</div>';
    var control = '<div class="control"><input type="text"></input></div>'
    return '<div class="conver" data-id="' + id +
        '" style="background:' + getConverBGColor() + ';">' + heading + body + control + '</div>';
}

function appendMsg(conver, pmObj) {
    conver.PM.push(pmObj);
    var msgHtml = getPMHtml(pmObj);
    var bodyDom = $("#easychat-conver div[data-id='" + conver.ID + "'] .body");
    $(bodyDom).append(msgHtml);
    scrollToBottom(bodyDom[0])
}

function scrollToBottom(dom) {
    dom.scrollTop = dom.scrollHeight;
}

function refreshDate() {
    $('#easychat-conver .conver .msg').each(function (i, o) {
        var dt = $(o).data('d');
        if (dt) {
            var date = new Date(dt);
            $(o).attr('title', moment(date).fromNow());
        }
    });
}
function refreshUnreadPMCount() {
    var c = getUnreadPMCount();
    document.title = (c > 0 ? "(" + c + ") " : "") + windowTitle;
}

function getUnreadPMCount(converId) {
    var c = 0;
    $(conversations).each(function (i, o) {
        if (typeof (converId) != "undefined" && o.ID == converId) {
            var eachC = $(o.PM).filter(function (i, o) { return !o.Read; });
            c += eachC.length;
        }
        else {
            var eachC = $(o.PM).filter(function (i, o) { return !o.Read; });
            c += eachC.length;
        }
    });
    return c;
}
function clearUnreadPMCount(converId) {
    var conver = _getConverByID(converId);
    if (conver) {
        $(conver.PM).each(function (i, o) { o.Read = true; });
    }
}


function getConverBGColor() {
    return 'rgba(100,100,100,' + opacVal + ')';
}

function getPrettyName(name) {
    if (minimized) {
        var names = "";
        $(name.split(" ").slice(0, 2)).each(function (i, o) {
            names += o[0];
        });
        return names;
    }
    return name;
}

function _getConverByID(converId) {
    var filter = $(conversations).filter(function (i, o) {
        return o.ID == converId;
    });
    return filter.length > 0 ? filter[0] : null;
}

function processDragItem(e, converId) {
    var uri = e.originalEvent.dataTransfer.getData('text/uri-list');
    if (uri !== "") {
        var path = uri.split('?')[0].split('#')[0];
        var ext = path.substring(path.lastIndexOf('.') + 1, path.length).toLowerCase();
        var uriHtml = "";
        if (ext.match(/^(jpg|jpeg|png|gif|bmp)$/)) {
            uriHtml = "<img src='" + uri + "'/>";
        }
        else {
            uriHtml = "<a href='" + uri + "'>Link</a>";
        }

        sendPM(uriHtml, converId);
    }
}